package micotime.com.amap_plugin.map.model;

import android.os.Build;
import  micotime.com.amap_plugin.map.interpolator.AccelerationInInterpolator;
import android.view.animation.AnticipateInterpolator;
import android.view.animation.AnticipateOvershootInterpolator;
import android.view.animation.BounceInterpolator;
import android.view.animation.CycleInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;
import android.view.animation.OvershootInterpolator;

import androidx.interpolator.view.animation.FastOutLinearInInterpolator;
import androidx.interpolator.view.animation.FastOutSlowInInterpolator;
import androidx.interpolator.view.animation.LinearOutSlowInInterpolator;

import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.maps.model.animation.AlphaAnimation;
import com.amap.api.maps.model.animation.Animation;
import com.amap.api.maps.model.animation.RotateAnimation;
import com.amap.api.maps.model.animation.ScaleAnimation;
import com.amap.api.maps.model.animation.TranslateAnimation;

import java.util.Map;


public class UnifiedMarkerOptions {
    private MarkerOptions markerOptions;
    private Interpolator baseInterpolator;
    private Animation animation;

    public UnifiedMarkerOptions(MarkerOptions markerOptions,
                                 Map<String, Object> animation) {
        this.markerOptions = markerOptions;
        if (animation == null) {
            return;
        }
        Object objInterpolatorType = animation.get("interpolatorType");
        Object objInterpolatorValue = animation.get("interpolatorValue");
        Object objAnimationType = animation.get("animationType");
        Object objDuration = animation.get("duration");
        Object objRepeatCount = animation.get("repeatCount");
        Object objRepeatMode = animation.get("repeatMode");

        int repeatCount = 0;
        long duration = 1000L;
        if (objDuration != null) {
            duration = (long) objDuration;
        }
        if (objRepeatCount != null) {
            repeatCount = (int) objRepeatCount;
        }
        if (objAnimationType == null) return;
        String animationType = objAnimationType.toString();

        switch (animationType) {
            case "rotate":
                Object objFromdegree = animation.get("fromdegree");
                Object objTodegree = animation.get("todegree");
                if (objFromdegree == null || objTodegree == null) return;
                this.animation = new RotateAnimation(Float.parseFloat(objFromdegree.toString()),
                        Float.parseFloat(objTodegree.toString()));
                break;
            case "alpha":
                Object objFromAlpha = animation.get("fromAlpha");
                Object objToAlpha = animation.get("toAlpha");
                if (objFromAlpha == null || objToAlpha == null) return;

                this.animation = new AlphaAnimation(
                        Float.parseFloat(objFromAlpha.toString()),
                        Float.parseFloat(objToAlpha.toString()));
                break;
            case "scale":
                Object objFromX = animation.get("fromX");
                Object objToX = animation.get("toX");
                Object objFromY = animation.get("fromY");
                Object objToY = animation.get("toY");
                if (objFromX == null || objToX == null || objFromY == null || objToY == null)
                    return;
                this.animation = new ScaleAnimation(
                        Float.parseFloat(objFromX.toString()),
                        Float.parseFloat(objToX.toString()),
                        Float.parseFloat(objFromY.toString()),
                        Float.parseFloat(objToY.toString()));
                break;
            case "translate":
                Object objLat = animation.get("targetLat");
                Object objLng = animation.get("targetLng");
                if(objLat != null && objLng != null){
                this.animation = new TranslateAnimation(new LatLng((double)objLat,(double)objLng));
            }
                break;
        }

        if (this.animation == null) return;
        this.animation.setDuration(duration);
        this.animation.setRepeatCount(repeatCount);
        if (objRepeatMode != null) this.animation.setRepeatMode((int) objRepeatMode);

        if (objInterpolatorType == null) return;
        switch (objInterpolatorType.toString()) {
            case "BounceInterpolator":
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
                    this.baseInterpolator = new BounceInterpolator();
                }
                break;
            case "DecelerateInterpolator":
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
                    if (objInterpolatorValue != null) {
                        this.baseInterpolator = new DecelerateInterpolator(Float.parseFloat(objInterpolatorValue.toString()));
                    } else {
                        this.baseInterpolator = new DecelerateInterpolator();
                    }
                }
                break;
            case "LinearInterpolator":
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
                    this.baseInterpolator = new LinearInterpolator();
                }
                break;
            case "LinearOutSlowInInterpolator":
                this.baseInterpolator = new LinearOutSlowInInterpolator();
                break;
            case "AnticipateInterpolator":
                if (objInterpolatorValue != null) {
                    this.baseInterpolator = new AnticipateInterpolator(Float.parseFloat(objInterpolatorValue.toString()));
                } else {
                    this.baseInterpolator = new AnticipateInterpolator();
                }
                break;
            case "AnticipateOvershootInterpolator":
                if (objInterpolatorValue == null) {
                    this.baseInterpolator = new AnticipateOvershootInterpolator();
                } else {
                    this.baseInterpolator = new AnticipateOvershootInterpolator(Float.parseFloat(objInterpolatorValue.toString()));
                }
                break;
            case "CycleInterpolator":
                this.baseInterpolator = new CycleInterpolator(objInterpolatorValue == null ? 0 : Float.parseFloat(objInterpolatorValue.toString()));
                break;
            case "FastOutLinearInInterpolator":
                this.baseInterpolator = new FastOutLinearInInterpolator();
                break;
            case "FastOutSlowInInterpolator":
                this.baseInterpolator = new FastOutSlowInInterpolator();
                break;
            case "OvershootInterpolator":
                if (objInterpolatorValue != null) {
                    this.baseInterpolator = new OvershootInterpolator(Float.parseFloat(objInterpolatorValue.toString()));
                } else {
                    this.baseInterpolator = new OvershootInterpolator();
                }
                break;
            case "AccelerationInInterpolator":
                this.baseInterpolator = new AccelerationInInterpolator();
                break;
        }
        if (this.baseInterpolator != null && this.animation != null) {
            this.animation.setInterpolator(this.baseInterpolator);
        }
    }

    public MarkerOptions getMarkerOptions() {
        return markerOptions;
    }

    public void setMarkerOptions(MarkerOptions markerOptions) {
        this.markerOptions = markerOptions;
    }

    public Animation getAnimation() {
        return animation;
    }

    public void setAnimation(Animation animation) {
        this.animation = animation;
    }
}
